package com.examsys.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class DBUtil {
	
	private static final ThreadLocal threadLocal = new ThreadLocal();// 存放session的线程池

	private static SessionFactory factory;

	static {
		StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
				.configure("hibernate.cfg.xml").build();// 将文件信息加载到内存中
														// .创建一个配置对象，用于读取配置

		Metadata metadata = new MetadataSources(standardRegistry)
				.getMetadataBuilder()
				.applyImplicitNamingStrategy(
						ImplicitNamingStrategyJpaCompliantImpl.INSTANCE)
				.build();

		factory = metadata.getSessionFactoryBuilder().build();

	}

	/**
	 * 获得数据库连接对象的方法
	 * 
	 * @return
	 * @throws Exception
	 */
	public static synchronized Session getSession() throws Exception {
		Session session = (Session) threadLocal.get();// 从线程池中拿出数据库连接对象
		try {
			if (session == null) {// 如果没有拿到数据库连接对象,则打开一个新的连接供使用
				session = factory.openSession();
//				session = factory.getCurrentSession();
				threadLocal.set(session);// 把打开的连接对象存放线程池中，供下次使用省掉创建连接的时间
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("数据库访问失败..");
		}
		return session;
	}
	
	/**
     * 关掉数据库连接对象
     * @throws Exception
     */
    public static void closeSession()
            throws Exception {
    	Session session = (Session) threadLocal.get();//从线程池中拿出数据库连接对象
        if ((session != null) && (session.isOpen())) {//如果拿到数据库连接对象,则关闭连接
            try {
                session.close();//关闭连接
            } catch (Exception e) {
                throw new Exception("关闭数据库连接失败..");
            }
            threadLocal.set(null);//从线程池中清掉此数据库连接对象
        }
    }
    
    /**
     * 开始事务的方法
     * @throws Exception
     */
    public static void begin() throws Exception {
        Transaction transaction = getSession().beginTransaction();
        if(transaction!=null&&!transaction.isActive()){
        	transaction.begin();//开始事务
        }
    }
    
    /**
     * 提交事务的方法
     * @throws Exception
     */
    public static void commit() throws Exception {
        Transaction transaction = getSession().getTransaction();
        if(transaction!=null){
        	transaction.commit();//提交事务
        }
    }
    
    /**
     * 回滚事务的方法
     */
    public static void rollback() {
        try {
        	Transaction transaction = getSession().getTransaction();
            if(transaction!=null){
            	transaction.rollback();//回滚事务的方法
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 关掉会话，释放资源
     * @param session
     */
    public static void close(Session session) {
        if (session != null) {
            try {
            	session.close();//关掉session，释放资源
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
